package com.eliaukjq.xunlianying;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author : 佩萁
 * Description :
 * @Create : 2024/7/8 - 9:47
 */
/**
 * 主类，用于演示多线程环境下变量安全性的问题。
 */
public class duoxiancheng {
    public static void main(String[] args) throws InterruptedException {
        // 定义线程数量
        final int threadSize = 500;
        // 创建一个不安全的示例对象
        ThreadUnSafeExample example = new ThreadUnSafeExample();
        // 使用计数器门闩来等待所有线程完成执行
        final CountDownLatch countDownLatch = new CountDownLatch(threadSize);
        // 创建一个线程池，用于执行多个线程
        ExecutorService executorService = Executors.newCachedThreadPool();
        // 循环启动线程，每个线程执行一次增加操作
        for (int i = 0; i < threadSize; i++) {
            executorService.execute(() -> {
                // 尝试增加示例对象的计数器
                example.add();
                // 计数器减一，表示一个线程已完成
                countDownLatch.countDown();
            });
        }
        // 等待所有线程完成执行
        countDownLatch.await();
        // 关闭线程池，防止资源泄漏
        executorService.shutdown();
        // 输出最终的计数结果
        System.out.println(example.get());
    }
}

/**
 * 一个线程不安全的示例类。
 * 其中的方法add在多线程环境下可能会导致数据不一致的问题。
 */
class ThreadUnSafeExample {
    // 初始化计数器
    private int count = 0;

    /**
     * 尝试增加计数器的值。
     * 由于没有同步机制，多个线程同时调用可能导致计数器增加的次数少于预期。
     */
    public void add() {
        count++;
    }

    /**
     * 获取当前计数器的值。
     *
     * @return 当前计数器的值。
     */
    public int get() {
        return count;
    }
}
